/*
 * viewer.h
 *
 *  Created on: Apr 30, 2011
 *      Author: tqlong
 */

#ifndef VIEWER_H_
#define VIEWER_H_

#include <armadillo>
#include <QtGui/QPainter>
#include <QtGui/QWidget>
#include "../data/dataset.h"
class QPointF;

/** Axis : Plot boundary class */
class Axis
{
protected:
  QWidget *m_widget;
  double m_xmin, m_ymin, m_xmax, m_ymax;
public:
  Axis(QWidget* w) :
    m_widget(w), m_xmin(-10), m_ymin(-10), m_xmax(10), m_ymax(10)
  {
  }
  QPointF
  point(double x, double y);
  QPointF
  reversePoint(const QPointF& p);
  QPointF
  point(const arma::vec& v);
  void
  setBoundary(double xmin, double xmax, double ymin, double ymax)
  {
    m_xmin = xmin;
    m_xmax = xmax;
    m_ymin = ymin, m_ymax = ymax;
  }
  QPointF
  distance(double x, double y);
};

/** Plotter : derived from QPainter
 */
class Plotter : public QPainter, public Axis
{
public:
  Plotter(QWidget* w) :
    QPainter(w), Axis(w)
  {
  }
};

class Viewer
{
  std::string m_fName;
  std::string m_format;
  InMemoryDataset m_set;
public:
  Viewer()
  {
  }
  Viewer(const std::string& fName, const std::string& format);
  virtual void
  plot(Plotter& pl); // derived classes reimplement this method
  virtual void
  reload();
};

namespace common
{
  void
  drawVVec(const std::vector<arma::vec>& vvec, Plotter& pl, const QPen& pen);

  template<typename D>
    void
    drawDSet(D& vvec, Plotter& pl, const QPen& pen, bool number = false)
    {
      pl.setPen(pen);
      int n = vvec.n();
      for (int i = 0; i < n; i++)
        {
          const typename D::vec_type& p = vvec.get(i);
          pl.drawEllipse(pl.point(p), 2.0, 2.0);
          if (number)
            {
              pl.drawText(pl.point(p), QString::number(i));
            }
        }
    }
}
#endif /* VIEWER_H_ */
